home *** CD-ROM | disk | FTP | other *** search
- DEFINT A-Z
-
- ' ONLINE HELP FOR LANGWIN ROUTINES
-
- ' Hit F2 to see list of routines
- ' (same names as LangWin routines,
- ' except corresponding help routines end with a period).
-
-
- ' The following routines are documented:
- DECLARE FUNCTION ActivateButton. ()
- DECLARE FUNCTION BlankWin. ()
- DECLARE SUB ChangeButtonFocus. ()
- DECLARE FUNCTION ChangeDir. ()
- DECLARE FUNCTION ChangeDrive. ()
- DECLARE FUNCTION CloseWindow. ()
- DECLARE FUNCTION DeactivateButton. ()
- DECLARE SUB GetButtonPress. ()
- DECLARE FUNCTION GetCurDir.$ ()
- DECLARE FUNCTION GetCurDrive.$ ()
- DECLARE FUNCTION GetFileNames. ()
- DECLARE SUB GetMousePos. ()
- DECLARE FUNCTION GetVerNum.$ ()
- DECLARE FUNCTION GrowScrollText. ()
- DECLARE SUB HideMouseCursor. ()
- DECLARE FUNCTION InitMouse. ()
- DECLARE FUNCTION IsWinOpen. ()
- DECLARE SUB LangWinInit. ()
- DECLARE FUNCTION MakeBox. ()
- DECLARE FUNCTION MakeCheckBox. ()
- DECLARE FUNCTION MakeHorizLine. ()
- DECLARE FUNCTION MakeInputField. ()
- DECLARE FUNCTION MakePushButton. ()
- DECLARE FUNCTION MakeVertLine. ()
- DECLARE FUNCTION MouseExists. ()
- DECLARE SUB NewFocusWindow. ()
- DECLARE FUNCTION OpenScrollWindow. ()
- DECLARE SUB RefreshScrollText. ()
- DECLARE SUB ReShowInputField. ()
- DECLARE SUB ReShowPage. ()
- DECLARE SUB ReShowText. ()
- DECLARE SUB SetColor. ()
- DECLARE SUB SetMousePos. ()
- DECLARE SUB SetXLimit. ()
- DECLARE SUB SetYLimit. ()
- DECLARE SUB ShowMouseCursor. ()
- DECLARE FUNCTION ShowTitle. ()
- DECLARE FUNCTION ShowWinText. ()
- DECLARE SUB WaitTicks. ()
- DECLARE FUNCTION WinEvent. ()
-
- END
-
- FUNCTION ActivateButton.
-
- 'Purpose:
- '--------
- ' Activate a button by restoring its text.
- ' When the button was deactivated (see DeactivateButton function),
- ' it's text was cleared and WinEvent no longer recognized clicks on
- ' the button. This function is used to reset the text so that WinEvent
- ' will recognize it and user can again click the button.
-
- ' Window containing the button will be given focus before the
- ' button's text is restored. User has option whether or not
- ' to return focus to the window that was current when ActivateButton
- ' was called.
-
- ' (New with V2.0)
- ' (Button's text no longer needed as a parameter with V2.1)
-
- 'Routine Type:
- '-------------
- ' Function.
-
-
-
- 'Parameters:
- '-----------
- ' ButtonHandle - handle of button to be activated
-
- ' FocusSw - switch to determine if window that was current when
- ' ActivateButton was called should be given focus back
- ' after button has been activated. ActivateButton WILL
- ' give focus to the window containing the button before
- ' it updates the text. This could produce one change in
- ' focus (depending on which window had focus when function
- ' was called). After the button has been activated, you can
- ' either leave focus in the window containing the button,
- ' or give focus back to the original window (may produce
- ' another focus change on screen). See Notes below for
- ' more details on using this parameter.
-
- ' = 0 do not change focus back to original
- ' = 1 change focus back to original window
- '
-
-
-
- '
- 'Return Values:
- '--------------
- ' 0 - button successfully activated
- ' 1 - ButtonHandle was not within index range
- ' of ButtonsData array. Typically, ButtonHandle
- ' should be between 1 and MaxButtons.
- ' 2 - ButtonHandle was within range, but it did
- ' not have a corresponding open window. This
- ' probably means ButtonHandle was incorrect.
- ' 3 - ButtonHandle did not correspond to a push
- ' button.
-
-
- 'Notes:
- '------
- ' With LangWin V2.1, the text of the button being activated is no longer
- ' required as an input parameter. The button's original text is remembered
- ' when it is deactivated, and will automatically be displayed when the
- ' button is activated. If you used the string passed to the V2.0 version
- ' ActivateButton to change the button's text, then you must now update
- ' the contents of ButtonsText(han) instead, where han is the button's
- ' handle. In this case, do not place a string into ButtonsText that
- ' exceeds the button's length which is found in ButtonsData(han,4).
-
-
- ' Some comments on the use of the FocusSw parameter:
- ' Typically, ActivateButton is called just after closing a child window to
- ' re-activate a button in the parent window. In this case, you cannot be
- ' sure the parent window had focus when you call ActivateButton (after
- ' closing the child). The close routine gives focus to the next window on
- ' the stack (which can change dynamically depending upon what window the
- ' user clicked last before closing the child). If the parent was not the
- ' last window on the stack, then ActivateButton will have caused one
- ' change in focus (it automatically gives focus to the window with the
- ' given button before changing its text). Thus, leaving focus in the window
- ' with the button (i.e., the parent) will be less disruptive visually.
- ' Call ActivateButton with the FocusSw set to 0 to leave focus in window
- ' with the given button.
-
-
- END FUNCTION
-
- FUNCTION BlankWin.
-
- 'Purpose:
- '--------
- ' Open/display an empty window.
- ' New window is given focus.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'V2.0 Changes:
- '-------------
- ' Negative value for WinColor% will make window unmovable.
- ' New ModeSw% parameter required.
- ' Negative value for ModeSw% will make window shadowless.
- ' Return values changed:
- ' Negative value returned if window not opened successfully.
- ' Window's number (>0) returned if window is opened successfully.
- ' 0 is not a valid return code.
- ' -12 is a new return code.
-
- 'Parameters:
- '-----------
- ' StartRow%: starting row (upper left)
- ' StartCol%: starting column (upper left)
- ' EndRow%: ending row (bottom right)
- ' EndCol%: ending column (bottom right)
- ' WinColor%: color attribute of window (0-15)
- ' (NEGATIVE value will make window unmovable)
- ' BorderColor%: color attribute of border (0-15)
- ' (NEGATIVE value will prevent window from being resized)
- ' BorderType%: 1=single line; 2=double line
- ' TextColor%: color attribute for scrollable text in the window (0-15)
- ' (since BlankWin has no scrollable text, this attribute
- ' is only used for the close icon if present)
- ' CloseIcon%: 1=display a close icon; 0=no close icon
- ' [regardless of whether a close icon is displayed, the ESC
- ' key will always generate a close action]
- ' [cannot specify a close icon for a window with ModeSw=4]
- ' ModeSw% Mode of window (effects how/if/when WinEvent returns
- ' control after an action has taken place)
- ' (NEGATIVE value for mode will generate a shadowless window):
- ' 1 = modeless window (normal). if modeless window has
- ' focus, user can click on any other visible window
- ' and it will be given focus by WinEvent. WinEvent will
- ' continue to process the new window until an action
- ' is taken in the current window.
- ' 2 = modal window. if modal window has focus, any attempt
- ' to click on another window will be ignored by WinEvent.
- ' this type of window can be used to display a message,
- ' and force user to close the window before continuing
- ' (e.g., for error messages).
- ' 3 = immediate close window. if this type window has focus,
- ' clicking on another window, or even the wallpaper, will
- ' cause WinEvent to return a close action (1). This can be
- ' used for menu windows that should be closed if user
- ' clicks somewhere else on the screen.
- ' 4 = wallpaper window. can never be selected, only serves as
- ' background for other windows (usually of same color
- ' as the wallpaper window). since wallpaper windows can
- ' never be given focus, they should not be given any
- ' objects (buttons, etc) and cannot have a close icon.
-
- 'Return Values:
- '--------------
- ' >0: window opened successfully (win number returned)
- ' -1: not enough storage to open another new window.
- ' [must increase value of MaxWindows global parameter]
- ' -2: not enough room for window's rows (+1 for shadow) on screen
- ' -3: not enough room for window's columns (+2 for shadow) on screen
- ' -4: window's color attribute out of range (must be 0-15)
- ' -5: window's border color attribute out of range (must be 0-15)
- ' -6: invalid value for BorderType (must be -1 or -2)
- ' -7: text color attribute out of range (must be 0-15)
- ' -8: window not long enough (must be >=3)
- ' -9: window not wide enough (must be >=3)
- '-10: [not used]
- '-11: [not used]
- '-12: invalid value for window mode (ModeSw) - must be 1 to 4
- '
-
- 'Notes:
- '------
- ' You MUST check to see if window opened successfully (return code>0)
- ' before calling any other LangWin functions or routines.
- ' Otherwise, you will either get errors (such as Illegal Function Call,
- ' Subscript Out of Range, etc.) or process the previously opened window
- ' by mistake.
-
- ' BlankWin sets the global variable AnyWinOpen to TRUE.
- ' this can be used to control a DO/LOOP that executes WinEvent
- ' as long as there is an open window on the screen. However, if an
- ' information only window is open, then you must use another criteria to
- ' end the DO/LOOP because the info only window will always be open.
- ' In this case, termination should occur when a close action
- ' occurs in the main window.
-
- END FUNCTION
-
- SUB ChangeButtonFocus.
-
- 'Purpose:
- '--------
- ' Change the visual appearance of a given button or check box.
- ' Either display its text in reverse video (background/foreground) to show
- ' it has focus, or display its text in normal video (foreground/background).
-
- ' This routine only changes the physical appearance of the button/check box,
- ' it does NOT give it focus logically (see notes below).
-
- ' Typical use would be to give a specific button/check box focus
- ' when a window is first created. In this way, the object could
- ' serve as the "default" choice (i.e., user could select the
- ' default by clicking it with the mouse, or by just hitting ENTER
- ' since the default would already have focus).
-
- ' Assumes that window containing the button/check box has focus.
- ' If it does not, call NewFocusWindow first to give focus to appropriate
- ' window.
-
- '
-
- 'Routine Type:
- '-------------
- ' Subroutine
-
-
- 'Parameters:
- '-----------
- ' Handle: handle of button or check box
- ' Switch: 0 = give focus (reverse video)
- ' 1 = clear focus (normal video)
-
-
- 'Notes:
- '------
- ' This routine only changes the visual appearance of the object.
- ' To change the logical appearance (i.e., so that other LangWin
- ' routines will recognize whether or not the object has focus),
- ' you must update the appropriate data structure. In this case,
- ' WinParms(CurWinPtr, 16) must be set.
-
- ' When giving an object focus (i.e., Switch=0), then the object's
- ' handle must be placed into the data structure as follows:
- ' WinParms(CurWinPtr,16)=han ' give object logical focus
- ' CALL ChangeButtonFocus(han, 0) ' give object physical focus
-
- ' When clearing focus (i.e., Switch=1), then the data structure must
- ' be set to show that no object has focus:
- ' WinParms(CurWinPtr,16)=-1 ' clear logical focus
- ' CALL ChangeButtonFocus(han, 1) ' clear physical focus
- '
-
- END SUB
-
- FUNCTION ChangeDir.
-
- 'Purpose:
- '--------
- ' Causes the directory specified in the calling parameter to
- ' become the default for the drive specified. Does NOT change the default
- ' drive (see ChangeDrive). If calling parameter has no drive spec, then
- ' the default drive is assumed.
- '
- ' (New with V2.0)
-
-
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' PathName$ - defines the drive (optional) and directory to become current.
- ' If drive included, then the default directory for that
- ' drive is set to the directory specified.
- ' If the drive is omitted, then the default drive is assumed,
- ' and the default directory for that drive is set.
- ' Either upper or lower case is acceptable.
- ' Examples - a:\my\programs (drive a:'s dir is changed)
- ' B:test (drive b:'s dir is changed)
- ' \some\stuff (default drive's dir is changed)
- '
-
-
- 'Return Values:
- '--------------
- ' 0: Change directory was successful.
- ' -1: PathName$ parameter was invalid.
- ' Could be caused by an invalid drive letter,
- ' or invalid directory specification.
- ' -2: Some other error occurred.
- ' OutRegs.ax contains the DOS extended error code.
- '
- 'Notes:
- '------
- ' This function calls DOS interrupt 21h, function 3Bh.
- '
- ' Also see: ChangeDrive, GetCurDir$, GetCurDrive$
- '
-
- ' ChangeDir will change the defualt directory on the drive specified.
- ' The default drive is NOT changed (see ChangeDrive). For example,
- ' if C: is the default drive and ChangeDir("a:\mydir") is executed,
- ' then the default directory on drive A: becomes \mydir, BUT the default
- ' drive still remains C:.
-
- ' If the specified drive is not ready, your program will get the
- ' standard "not ready" error condition. You can use an ON ERROR routine
- ' to trap this condition. The user can be given two alternatives: either
- ' RETRY (use a RESUME) or IGNORE (use a RESUME NEXT).
-
- END FUNCTION
-
- FUNCTION ChangeDrive.
-
- 'Purpose:
- '--------
- ' Change the default drive.
- '
- ' (New with V2.0)
- '
-
-
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' DriveLetter$ - Letter to become new default drive.
- ' Can be either upper or lower case.
- ' Only the first character in DriveLetter$ string
- ' will be examined. Cannot be a null string.
- '
- '
- 'Return Values:
- '--------------
- ' >0: The number of logical drives specified by the LASTDRIVE
- ' parameter in CONFIG.SYS. However, if fewer than 5 drives
- ' is specified in LASTDRIVE, then the value of 5 is returned
- ' (sorry, this is a DOS quirk, not mine).
- ' -1: Could not change to the specified drive (drive letter
- ' specified was probably not a valid drive).
- ' -2: DriveLetter$ was not a letter.
- '
- 'Notes:
- '------
- ' This function calls DOS interrupt 21h, function 0Eh.
- '
- ' Also see: ChangeDir, GetCurDir$, GetCurDrive$
- '
-
- ' ChangeDrive will not actually cause I/O to the specified drive.
- ' Thus, it does not care if the specified drive is ready.
- ' You can use ChangeDrive to determine the actual drives
- ' configured on a system. Just loop through every possible
- ' letter, and issue a ChangeDrive command for it. If return code
- ' is 0, then drive letter exists (but you don't know if it's ready).
-
-
- END FUNCTION
-
- FUNCTION CloseWindow.
-
- 'Purpose:
- '--------
- ' Close/erase the current window.
- ' If you want to close a window that is not current,
- ' call NewFocusWindow to first bring it into focus.
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' None (the current window is automatically closed).
- '
- '
- 'Return Values:
- '--------------
- ' 0: window closed successfully
- ' 1: there were no windows currently open when this routine was called
-
-
- 'Notes:
- '-------
- ' When the last window is closed, the global variable AnyWinOpen
- ' will be set to FALSE.
- ' This variable can be used to control a DO/LOOP that executes WinEvent
- ' as long as there is an open event on the screen. However, if a Mode 4
- ' window is open, then you must use another criteria to
- ' end the DO/LOOP because the info only window will always be open.
- ' In this case, termination should occur when a close action
- ' occurs in the main window.
-
- ' Since CloseWindow only operates on the current window, if you want to
- ' close a specific window, and are not sure it's current, use the following
- ' technique (assume the variable win1 contains the number of the window
- ' to be closed):
- ' IF IsWinOpen(win1, han) THEN ' if win1 is open, get its handle
- ' zz = CurWinPtr ' save handle of current window
- ' CALL NewFocusWindow(han) ' make win1 current
- ' xx = CloseWindow ' close it
- ' CALL NewFocusWindow(zz) ' make original win current again
- ' END IF
-
-
- ' There's another "short-cut" you can use if you just want to close ALL open
- ' windows (if you want to close a sub-set of all possible windows,
- ' use the above technique with the numbers of each window to be closed).
- ' To easily close ALL open windows:
-
- ' FOR i = LastWinStack TO 1 STEP -1
- ' CALL NewFocusWindow(WinStack(i))
- ' x = CloseWindow
- ' NEXT
-
- ' The WinStack array contains the handles of all open windows, in the order
- ' in which they appear on the screen. LastWinStack is a global variable
- ' pointing to the current slot. Thus WinStack(1) contains the handle of the
- ' first window opened, and WinStack(LastWinStack) contains the handle of the
- ' window with focus. The above code just closes each window, from the most
- ' current to the least current.
-
-
- END FUNCTION
-
- FUNCTION DeactivateButton.
-
- 'Purpose:
- '--------
- ' Deactivate a button by setting its text to null (equivalent to
- ' "fading" the button's text seen in other GUIs). Once the button is
- ' cleared, user can no longer click on it (WinEvent will not recognize
- ' the click). This can be used to prevent a user from re-clicking
- ' a button until the button's corresponding activity has been completed
- ' and your program has re-activated it (see ActivateButton function).
-
- ' Window containing the button will be given focus before the
- ' button's text is cleared. User has option whether or not
- ' to return focus to the window that was current when DeactivateButton
- ' was called.
-
- ' (New with V2.0)
-
-
-
- 'Routine Type:
- '-------------
- ' Function.
-
-
-
- 'Parameters:
- '-----------
- ' ButtonHandle - handle of button to be activated
-
- ' FocusSw - switch to determine if window that was current when
- ' DeactivateButton was called should be given focus back
- ' after button has been cleared. DeactivateButton WILL
- ' give focus to the window containing the button before
- ' it clears the text. This could produce one change in
- ' focus (depending on which window had focus when function
- ' was called). After the button has been cleared, you can
- ' either leave focus in the window containing the button,
- ' or give focus back to the original window (may produce
- ' another focus change on screen). See Notes below for
- ' more details on using this parameter.
-
- ' = 0 do not change focus back to original
- ' = 1 change focus back to original window
-
-
-
-
- '
- 'Return Values:
- '--------------
- ' 0 - button successfully cleared.
- ' 1 - ButtonHandle was not within index range
- ' of ButtonsData array. Typically, ButtonHandle
- ' should be between 1 and MaxButtons.
- ' 2 - ButtonHandle was within range, but it did
- ' not have a corresponding open window. This
- ' probably means ButtonHandle was incorrect.
- ' 3 - ButtonHandle did not correspond to a push
- ' button.
-
-
- 'Notes:
- '------
- ' Some comments on the use of the FocusSw parameter:
- ' Typically, DeactivateButton is called after a button is clicked to
- ' clear the button's text. Once the text is cleared, WinEvent will no
- ' longer recognize clicks on the button and it will be deactivated.
- ' If DeactivateButton is called immediately after detecting the button
- ' click action (3) returned by WinEvent, and before any other window
- ' is open, then value of FocusSw does not matter (since window that
- ' had focus before the button was deactivated is the same as the window
- ' containing the button). In this case, regardless of which value
- ' (0 or 1) you assign to the FocusSw parameter, focus will remain in the
- ' window containing the button just cleared. You can then go open a child
- ' window (or whatever) based upon the meaning of the button clicked.
-
- ' Alternatively, you could detect the button click, open a child window
- ' (which would have focus after it's opened), call DeactivateButton to
- ' go back and clear the button, and set FocusSw=1 in the call to
- ' DeactivateButton to cause focus to be given back to the child.
- ' This will produce two focus changes (from newly opened child back
- ' to parent to clear the button, then from parent back to child).
- ' If windows overlap, this will be visually disturbing; I'm not sure
- ' why anyone would want to use this alternative. In any case, I've provided
- ' the FocusSw just in case you need it.
-
-
- END FUNCTION
-
- SUB GetButtonPress.
-
- 'Purpose:
- '--------
- ' Returns the current status (up/down) of ALL mouse buttons.
- ' For the button specified by input parameter, this routine also
- ' returns the number of presses and position of the mouse at the last
- ' press (in pixel coordinates). Number of presses is maintained by the
- ' mouse driver. It is reset by calling GetButtonPress. Other routines
- ' will also cause the count to be reset (see Notes below).
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' Button%: on INPUT, specifies the button to be checked
- ' [0 = left, 1 = right, 2 = center]
- ' : on OUTPUT, specifies CURRENT status of ALL mouse buttons
- ' [bits set as follows (shown left to right, bits 2 to 0)]:
- '
- ' ..0 left button up
- ' ..1 left button down
- ' .0. right button up
- ' .1. right button down
- ' 0.. center button (if present) up
- ' 1.. center button (if present) down
- '
- ' Count%: number of times the button specified by input parameter
- ' (Button) was pressed since the last time the count was
- ' reset (by a previous call to this routine or others that
- ' reset the count - see Notes below).
- '
- ' Horiz%: horizontal pixel coordinate of mouse when button specified
- ' by input parameter (Button) was last pressed.
- '
- ' Vert%: vertical pixel coordinate of mouse when button specified
- ' by input parameter (Button) was last pressed.
- '
- '
- 'Notes:
- '------
- ' This subroutine calls BIOS interrupt 33h, function 05h.
- '
- ' The input parameter: Button will be MODIFIED by this
- ' routine. On input, Button specifies the button to checked for
- ' position and press count. On output, Button specifies the
- ' up/down status of ALL buttons. Your program must NOT assume that
- ' the input parameter (Button) remains unchanged.
- '
- ' Horizontal/vertical coordinates returned are in PIXELS. If screen
- ' positions are desired, use integer division by width/depth of a
- ' screen character in pixels to get column/row.
- '
- ' Calling ShowMouseCursor and HideMouseCursor will also reset
- ' the count of button presses (maintained by the mouse driver).
- ' So, calling the "show" or "hide" routines while waiting for
- ' button press information can result in an inaccurate count
- ' (anyway, there should be no need to "hide" the mouse if you are
- ' counting the button presses).
- '
- ' The difference between GetButtonPress and GetMousePos is that
- ' GetButtonPress returns the coordinates for the mouse button specified
- ' by the input parameter (Button), at the point in time when that button
- ' was last pressed (count of presses is also returned).
- ' GetMousePos returns the CURRENT coordinates of the mouse, at the point
- ' in time when GetMousePos is called (regardless of whether or not any
- ' button was ever pressed).
- ' GetMousePos is used to "poll" the mouse in real-time to obtain its
- ' CURRENT position.
- ' GetButtonPress is used to get the mouse's position corresponding to
- ' the last time a specific button was pressed (and how many times it
- ' was pressed - useful for determining if a double click occurred).
- ' Both routines return CURRENT status (up/down) of all buttons.
-
- END SUB
-
- FUNCTION GetCurDir.$
-
- 'Purpose:
- '--------
- ' Determine the default directory on a specified drive.
- '
- ' (New with V2.0)
- '
-
-
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' DriveLetter$ - Letter of the drive to be checked.
- ' If null, then default drive is assumed.
- ' DriveLetter$ can be either upper or lower case.
- ' If DriveLetter$ is non-null, then only the first
- ' character in the string will be examined.
-
- '
- 'Return Values:
- '--------------
- ' If successful, string with: Fully qualified directory name.
-
- ' If unsuccessful, STRING with:
- ' "-1" - DriveLetter$ did not contain a letter.
- ' "-2" - Drive letter was invalid (not on the system).
- ' "-3" - Other error (DOS extended error code will
- ' be in OutRegs.ax).
- '
- 'Notes:
- '------
- ' This function calls DOS interrupt 21h, function 47h.
- '
- ' Also see: ChangeDir, ChangeDrive, GetCurDrive$
- '
- ' To determine success, test first character of returned string.
- ' If it was a "\", then function was successful, and returned string
- ' contains the fully qualified current directory on specified drive,
- ' If first character was a "-", then an error occurred; check rest of string
- ' to determine which error.
-
- ' If the specified drive is not ready, your program will get the
- ' standard "not ready" error condition. You can use an ON ERROR routine
- ' to trap this condition. The user can be given two alternatives: either
- ' RETRY (use a RESUME) or IGNORE (use a RESUME NEXT).
-
- END FUNCTION
-
- FUNCTION GetCurDrive.$
-
- 'Purpose:
- '--------
- ' Determine the current drive's letter.
- '
- ' (New with V2.0)
- '
-
-
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' None.
-
-
-
- 'Return Values:
- '--------------
- ' If successful, then string with: The current drive's letter.
- ' The trailing colon (:) is NOT
- ' included (length of string is 1).
- '
- ' If unsuccessful, then string with:
- ' "-1" DOS returned an invalid letter.
- '
- '
- 'Notes:
- '------
- ' This function calls DOS interrupt 21h, function 19h.
- '
- ' GetCurDrive does not actually do I/O to the drive (the current drive
- ' letter is obtained from an internal DOS data structure). Thus, the
- ' drive need not be ready when this function is used (any you can not assume
- ' that the drive is ready after this function has been used).
-
- ' Also see: ChangeDir, ChangeDrive, GetCurDir$
- '
-
-
- END FUNCTION
-
- FUNCTION GetFileNames.
-
- 'Purpose:
- '--------
- ' To extraxct file names or sub-dir names from the current or specified dir,
- ' and place them into the passed string array.
-
- ' (New with V2.0)
- ' (Modified V2.3)
- ' - Text$ array is dynamically REDIMed to the correct size
- ' - TypeSrch=3 option added
-
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' TypeSrch: type of search:
- ' = 1: directory names extracted that match filespec$
- ' (read-only, hidden, or system dir names NOT extracted)
- ' = 2: file names extracted that match filespec$
- ' (read-only, hidden, or system file names NOT extracted)
- ' = 3: ALL names that match filespec$ extracted.
- ' The first byte of the name is prefixed with
- ' a string whose decimal value corresponds to the
- ' file/dir's attribute. See Notes for examples.
-
- ' filespec$: specification for dir or file name (wildcards allowed).
- ' examples: "*.*", "*.bas"; "sample??.*" "c:\mylib\*.exe"
-
- ' Text$: String array to hold all file/dir entries matching filespec$.
- ' This array MUST be DYNAMIC. It will be REDIMed to the
- ' exact size to hold all names extracted, hence it can of
- ' any size when this function is called. LBOUND will be 1.
- ' UBOUND will be the number of files/dirs extracted.
- ' ORIGINAL CONTENTS OF Text$ ARRAY WILL BE DISTROYED.
- ' If TypeSrch=3, then LEFT$(Text$(i),1) will be set to the
- ' dir/file's attribute and the remaining characters will be
- ' the actual name. You'll have to test the attribute byte
- ' to determine what type of file/dir it is (and remove
- ' the attribute byte from the name before displaying it).
- ' See Notes for examples.
- '
- 'Return Values:
- '--------------
- ' >0 ==> normal exit - number of names extracted
- ' -1 ==> invalid value for TypeSrch (must be 1 or 2)
- ' -2 ==> no files/dirs matched filespec$
- ' -3 ==> NOT USED
- ' -4 ==> NOT USED
- ' -5 ==> path not found (filespec$ could be invalid)
- ' -6 ==> other error (OutRegs.ax has DOS extended error code)
- '
- '
- '
- '
- 'Notes:
- '------
- ' This function calls DOS interrupts 21h, function 4Eh, 4Fh, and 1Ah.
-
- ' GetFileNames can be used to extract file and/or dir names from the
- ' current dir (for subsequent display in a scrollable text window).
- '
- ' The string array passed to this function (Text$) will hold all
- ' names extracted. It will be REDIMed to the correct size. It MUST
- ' be DYNAMIC in the calling program. NOTE: THE ORIGINAL CONTENTS OF THE
- ' STRING (Text$) ARRAY WILL BE DISTROYED.
-
- ' If the Text$ array is not DYNAMIC, you'll get a "duplicate definition"
- ' error when you compile or run a program in the QB environment
- ' that calls the GetFileNames function.
-
- ' An array can be made DYNAMIC by inclucing a variable name in its
- ' original DIM statement
- ' (for example: DIM Text$ (1 to x) where x has been previously defined).
- ' Alternatively, you can make ALL arrays dynamic by including the
- ' meta-command '$DYNAMIC at the beginning of your main module.
- '
-
- ' If this function returns a value > 0, then Text$ contains the files
- ' or dirs (depending upon value of TypeSrch) that matched filespec$.
- ' Note that if you ask for all dirs (*.*), then two dir names you'll always
- ' get (except when in the root directory) are "." and ".." (i.e., the
- ' shorthand symbols for the current and parent directory).
- ' You can sort the Text$ array, and use RefrestScrollText to place
- ' new list into the current window.
- '
- ' To save string space, you can REDIM the Text$ array
- ' as 1 TO 1 prior to calling GetFileNames. GetFileNames will expand this
- ' array as necessary to hold all names that match the search criteria.
- ' After returning from GetFileNames, ERASE the Text$ array as soon as
- ' you are finished with it to save space.
-
- ' Example:
- ' '$DYNAMIC ' make all arrays dynamic
- ' REDIM Text$(1 TO 1) ' minimum size to save space
- ' .
- ' .
- ' rc=GetFileNames(2,"*.*",Text$()) ' get all file names
- ' IF rc < 0 THEN ' test for errors
- ' .
- ' END IF
- ' .
- ' .
- ' FOR i = 1 to rc ' rc contains number of files in array
- ' PRINT Text$(i) ' print file names
- ' NEXT
- ' .
- ' ERASE Text$ ' clear the array to save space
-
-
- ' Use TypeSrch=3 if you want to get ALL names in the current or specified
- ' directory that match filespec$. In this case, each name is prefixed with
- ' a one-byte string whose decimal value is the file/dir's attribute.
- ' Attribute bits can take the following values:
-
- ' BITS DECIMAL MEANING
- ' .... ...1 1 Read Only
- ' .... ..1. 2 Hidden
- ' .... .1.. 4 System
- ' .... 1... 8 Volume Label
- ' ...1 .... 16 Sub-Directory
- ' ..1. .... 32 Archive
- ' .1.. .... x UNUSED
- ' 1... .... x UNUSED
-
- ' Attribute bits can occur in combinations. For example, a file that is
- ' marked as Read Only and Hidden will have a decimal attribute byte of 3.
- ' "Regular" files will usually have a decimal attribute byte of 0 or 32.
- ' "Regular" directories will usually have a decimal attribute byte of 16.
-
- ' When TypeSrch=3 is used, you must test the first byte of each file name
- ' to determine its type, then remove the first byte if you are going to
- ' display the names:
-
- ' REDIM Text$(1 to 1)
- ' rc=GetFileNames(3,"*.bas",Text$) ' get all names that match *.bas
- ' IF rc < 0 THEN
- ' process the error
- ' END
- ' END IF
-
- ' test the attributes
- ' FOR i = 1 TO rc
- ' att=ASC(LEFT$(Text$(i),1)) ' get attribute byte
- ' IF att = zz THEN .... ' process the attribute byte
- ' x=LEN(Text$(i) ' get length
- ' Text$(i)=RIGHT$(Text$(i),x-1) ' strip attribute byte
- ' NEXT
-
- ' z=OpenScrollWindow( ........., Text$, .........) ' open scroll window
- ' ERASE Text$ ' save some string space
-
- END FUNCTION
-
- SUB GetMousePos.
-
- 'Purpose:
- '--------
- ' Returns the current status (up/down) of all mouse buttons
- ' and current position (in pixel coordinates).
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' Button%: the CURRENT status of all mouse buttons.
- ' [bits set as follows (shown left to right, bits 2 to 0)]:
- '
- ' ..0 left button up
- ' ..1 left button down
- ' .0. right button up
- ' .1. right button down
- ' 0.. center button (if present) up
- ' 1.. center button (if present) down
- '
- ' Horiz%: current horizontal pixel coordinate of mouse.
- ' Vert%: current vertical pixel coordinate of mouse.
- '
- '
- 'Notes:
- '------
- ' This subroutine calls BIOS interrupt 33h, function 03h.
- '
- ' Horizontal/vertical coordinates returned are in PIXELS. If screen
- ' positions are desired, use integer division by width/depth of
- ' character in pixels to get column/row.
- '
- ' The difference between GetButtonPress and GetMousePos is that
- ' GetButtonPress returns the coordinates for the mouse button specified
- ' by the input parameter (Button), at the point in time when that button
- ' was last pressed (count of presses is also returned).
- ' GetMousePos returns the CURRENT coordinates of the mouse, at the point
- ' in time when GetMousePos is called (regardless of whether or not any
- ' button was ever pressed).
- ' GetMousePos is used to "poll" the mouse in real-time to obtain its
- ' CURRENT position.
- ' GetButtonPress is used to get the mouse's position corresponding to
- ' the last time a specific button was pressed (and how many times it
- ' was pressed - useful for determining if a double click occurred).
- ' Both routines return CURRENT status (up/down) of all buttons.
-
- END SUB
-
- FUNCTION GetVerNum.$
-
- 'Purpose:
- '--------
- ' Returns version number of LangWin.
- ' [CTRL-A from any window will also display version number]
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' None.
- '
- '
- 'Return Values:
- '--------------
- ' String with version number.
-
-
- END FUNCTION
-
- FUNCTION GrowScrollText.
-
- 'Purpose:
- '--------
- ' This function allows you to dynamically add entries to the list of
- ' scrollable text in the CURRENT window. The text is appended to the
- ' end of the CURRENT window's scrollable text array, and the array
- ' is re-displayed in the CURRENT window.
- ' (New with V2.3)
-
-
- 'Routine Type:
- '-------------
- ' Function.
-
-
- 'Parameters:
- '-----------
- ' Text$ - text string to be added to end of CURRENT window's
- ' scrollable text array and displayed in the CURRENT
- ' window's scrollable text area.
-
-
- '
- 'Return Values:
- '--------------
- ' 0 - success
- ' -1 - current window is not a scrollable text window (i.e., it was
- ' not opened via OpenScrollText).
- ' -2 - no more room in scrollable text array for another entry.
- ' there's already MaxTextLines lines of text in the array.
- ' you'll either have to increase MaxTextLines, or handle
- ' the case where you allow the user to browse the list
- ' as it exists, then click a button to close the window, re-open it
- ' with null text, and continue filling the window's text area.
-
-
-
- 'Notes:
- '------
-
- ' If the list of scrollable text in the current window does not fill the
- ' text area defined when the window was opened, then the text string passed
- ' to GrowScrollText will be be displayed at the bottom of the visible list.
- ' If the list of scrollable text fills the text area, then text is scrolled
- ' up and the new string passed to GrowScrollText is displayed at the bottom
- ' of the text area. Note that the list of scrollable text could be null, in
- ' which case the first call to GrowScrollText will create the first line of
- ' scrollable text in the current window (but a scrollable text window must
- ' have been opened, otherwise GrowScrollText will not work properly).
-
- ' GrowScrollText will operate on the current window with focus. If that
- ' window is not a scrollable text window, no action is taken and an error
- ' code (-1) is returned (i.e., even if the scrollable text array is null,
- ' the window MUST have been opened with OpenScrollText and NOT with
- ' BlankWin). If the scrollable text array for the current window is already
- ' full (i.e., it has MaxTextLines lines of text already defined), no action
- ' is taken and an error code (-2) is returned.
-
- ' GrowScrollText can be used to give the user visual feedback as a long
- ' running task progresses. Suppose you have a routine that searches for
- ' specific records in a data base, and you want to display these in a
- ' scrollable list for your user to browse. GrowScrollText can be used to
- ' show the records being dynamically added to the list as they are found.
- ' The following pseudo code will implement this example:
-
-
- ' DIM Text(1 to 1) AS STRING ' scrollable text, init as null
- ' Above array need only have 1 entry (initially null). It's only used by
- ' OpenScrollText to initialize LangWin's data structure SaveText.
- ' Thereafter, GrowScrollText will actually "grow" the text in SaveText.
- ' .
- ' .
- ' w1=OpenScrollWindow( ..... ,Text(), .....) scrollable win with null text
- ' ' put some buttons in the window
- ' .
- ' .
- ' DO WHILE AnyWinOpen ' process windows
- ' wn=WinEvent(action) ' wait for an action
- ' ' process actions in windows
- ' .
- ' .
- ' .
- '
- ' ' assume that at this point you determine the need to search a
- ' ' database for records, and to display the results in a scrollable
- ' ' window (w1) where the user can browse the results.
- '
- ' ' w1 is the number of the open window that will contain the
- ' ' scrollable text. at this point, the scrollable text array is null.
- ' x=IsWinOpen(w1,Han) ' get handle of w1 and save in Han
- '
- ' ' search loop
- ' DO
- ' ' first, you must make sure window with text (w1) is current
- ' CALL NewFocusWindow(Han) ' give focus to text window
- '
- ' rec$=GetNextMatch$(parms) ' get a record
- ' IF rec$="" THEN EXIT DO ' see if search is done
- ' ' note: GetNextMatch$ is NOT part of LangWin. it's
- ' ' a fictitious function used to illustrate a routine
- ' ' that you might call to get a record and return in text string.
- ' ' i assume a null value is returned when search is completed.
- '
- ' rc=GrowScrollText(rec$) ' display rec in window
- ' SELECT CASE rc ' test above return code
- ' CASE -1 ' current window is not a scrollable text window
- ' ' process the error
- ' CASE -2 ' scrollable text array is full
- ' ' process the error. this might include allowing
- ' ' the user to browse the scrollable text and waiting
- ' ' for a CONTINUE button to be clicked. when this
- ' ' button is clicked, you could close the window,
- ' ' re-open it (to clear text), and continue the search.
- ' END SELECT
- '
- ' ' using the time-out techniques from Section 6.22, you could
- ' ' also include a STOP button to interrupt the search.
- ' ' assume handle of STOP button is: Stop1
- ' aa=-999 ' set time out option
- ' x=WinEvent(aa) ' wait for 0.5 sec for an event
- ' ' loop until STOP button is clicked
- ' LOOP UNTIL (aa=3 AND WinParms(CurWinPtr,16)=Stop1)
- '
-
- END FUNCTION
-
- SUB HideMouseCursor.
-
- 'Purpose:
- '--------
- ' Hides mouse cursor before displaying anything on the screen.
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' None.
- '
- '
- 'Notes:
- '------
- ' This subroutine calls BIOS interrupt 33h, function 02h.
- '
- ' The mouse cursor must be hidden before writing anything to the screen.
- ' Otherwise, any character written to the same position as the mouse
- ' cursor will not be displayed. See ShowMouseCursor for inverse function.
- '
- ' LangWin sets a global flag (HaveMouse) to true if mouse exists.
- ' This flag should be tested before calling HideMouseCursor:
- ' IF HaveMouse THEN CALL HideMouseCursor
- '
- ' Also see: ShowMouseCursor, MouseExists, and InitMouse.
-
- END SUB
-
- FUNCTION InitMouse.
-
- 'Purpose:
- '--------
- ' Initialize the mouse.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' NumButtons: number of buttons on the mouse
- '
- '
- 'Return Values:
- '--------------
- ' TRUE (-1): mouse was successfully initialized
- ' FALSE (0): mouse was not successfully initialized
- '
- '
- 'Notes:
- '------
- ' This function calls BIOS interrupt 33h, function 00h.
- '
- ' Also see: MouseExists.
- '
- ' MouseExists should be called BEFORE InitMouse to insure that
- ' a mouse exists. Otherwise, calling InitMouse without a mouse could
- ' crash the system. InitMouse must be called once to initialize the
- ' mouse before performing any other mouse functions.
-
- END FUNCTION
-
- FUNCTION IsWinOpen.
-
- 'Purpose:
- '--------
- ' Given a window number, determine if it is open (TRUE) or closed (FALSE).
- ' If open, determine the window's handle.
- ' (New with V2.0)
- '
-
- 'Routine Type:
- '-------------
- ' Function.
-
-
- 'Parameters:
- '-----------
- ' wn%: - window's number (input)
- ' wh% - window's handle if it's open, else -1 (output)
-
-
- 'Return Values:
- '--------------
- ' TRUE - window was open
- ' FALSE - window was not open
-
-
- 'Notes:
- '------
- ' WinNum array is scanned for match on window number.
- ' If match found, index in WinNum is the window's handle.
-
- ' IsWinOpen can be used to determine if a specific child window
- ' is open before closing the parent.
-
- ' All info for open windows are stored in data structures indexed
- ' by window's handle. If you know a window's number (returned by the
- ' corresponding "make" routine), then IsWinOpen can be used to determine
- ' if the window is open, and if so, its handle. The handle can be used
- ' as an index into the data structures to examine the window's status.
- ' The handle is also needed if you call NewFocusWindow to bring a new
- ' window into focus.
-
- END FUNCTION
-
- SUB LangWinInit.
-
- 'Purpose:
- '--------
- ' Initialize LangWin's global variables.
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' None.
- '
- '
- 'Notes:
- '------
- ' Must be called once in main module before performing any of LangWin's
- ' routines. LangWinInit will also initialize the mouse if it exists.
-
- ' if you get a "subscript out of range" error while
- ' in this routine, be sure you called QB with /ah.
- ' then try reducing the value of MaxWindows.
- ' check the WIDTH command; reduce number of columns,
- ' and/or number of rows.
-
- END SUB
-
- FUNCTION MakeBox.
-
- 'Purpose:
- '--------
- ' Draw a box in current window.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' StartBoxRow%: starting row (upper left)
- ' StartBoxCol%: starting column (upper left)
- ' EndBoxRow%: ending row (bottom right)
- ' EndBoxCol%: ending column (bottom right)
- ' BoxLinType%: 1 (single line); 2 (double line)
- ' BoxColor%: color attribute of box (0-15)
- '
- '
- 'Return Values:
- '--------------
- ' 0: box was successfully displayed
- ' 1: invalid box line type parameter (not a 1 or 2)
- ' 2: box would extend beyond current window.
- '
- '
- 'Notes:
- '------
- ' Starting/ending rows and columns are relative to the current window.
- ' Row 0, Column 0, represent the first row/column in the window,
- ' regardless of where the window is located on the screen
- ' (first /last row and columns contain the window's border).
- ' Box will not be drawn if it would extend beyond boundaries of the
- ' current window (or if it would overlay the boundary itself).
-
- END FUNCTION
-
- FUNCTION MakeCheckBox.
-
- 'Purpose:
- '--------
- ' Open/display a check box in the current window.
- ' Handle of check box will be returned.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' Row%: row where Check Box will be placed
- ' Col%: starting column
- ' Foreg%: foreground color attribute (0-15)
- ' Backg%: background color attribute (0-15)
- ' Default%: initial default state of Check Box
- ' [MUST either be CheckOn (box is selected/down),
- ' or CheckOff (box is not selected/up. CheckOn and
- ' CheckOff are global variables initialized by LangWinInit]
- '
- '
- 'Return Values:
- '--------------
- ' >0: check box successfully created (positive value is handle number)
- ' -1: check box would extend beyond current window
- ' -3: length not big enough for default box text
- ' [should not see this error since box text is pre-defined]
- ' -4: not enough storage for another button
- ' [must increase the value of global parameter MaxButtons]
- ' -5: foreground color attribute invalid (must be 0-15)
- ' -6: background color attribute invalid (must be 0-15)
- ' -7: shadow switch value invalid
- ' [should not see this error since shadow switch is pre-defined]
- ' -8: default box state not valid
- ' [it MUST be either CheckOn or CheckOff]
- '
- '
- 'Notes:
- '------
- ' MakeCheckBox calls MakePushButton to actually display the Check Box
- ' (since Check Boxes are really just another type of button).
- '
- ' Row and column are relative to the current window.
- ' Row 0, Column 0, represent the first row/column in the window,
- ' regardless of where the window is located on the screen
- ' (first /last row and columns contain the window's border).
- ' Check Box will not be opened if it would extend beyond boundaries
- ' of the current window (or if it would overlay the boundary itself).
- '
- ' The handle value returned must be saved.
- ' After calling WinEvent to wait for an event in the current window,
- ' you must determine which event occurred (see WinEvent for details).
- ' Depending upon the event, you may need to determine the state of
- ' Check Boxes in the window. Use the saved handles of all appropriate
- ' Check Boxes to index the ButtonsData array which contains the status
- ' of all buttons. The 7th entry for each button contains a switch
- ' that describes whether or not it has a shadow (1=yes; 0=no). For
- ' Check Boxes, the shadow determines if it was selected
- ' (1=shadow - box NOT selected; 0=no shadow - box was selected).
- '
- ' If Han represents the handle value of a specific Check Box, the
- ' following code illustrates how to determine if the box was selected:
- '
- ' IF ButtonsData(Han, 7) = 1 THEN ... the Check Box was NOT selected.
- ' IF ButtonsData(Han, 7) = 0 THEN ... the Check Box was selected.
-
- END FUNCTION
-
- FUNCTION MakeHorizLine.
-
- 'Purpose:
- '--------
- ' Draw a horizontal line across current window.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' Row%: row where line will be placed
- ' LineType%: type of line (1=single; 2=double)
- '
- '
- 'Return Values:
- '--------------
- ' 0: success
- ' 1: invalid line type parameter (must be 1 or 2)
- ' 2: line would extend beyond window boundary or
- ' fall on same row as border.
- '
- '
- 'Notes:
- '------
- ' Row where line is placed is relative to the current window.
- ' Row 0 represent the first row in the window,
- ' regardless of where the window is located on the screen
- ' (first /last row contains the window's border).
- ' Line will not be drawn if it would extend beyond boundaries of the
- ' current window (or if it would overlay the top/bottom boundary itself).
-
- END FUNCTION
-
- FUNCTION MakeInputField.
-
- 'Purpose:
- '--------
- ' Open/display an Input Field in the current window
- ' [to be used for data entry/modification]
- ' [can also be used for entering a password - see length field parameter]
- '
- 'Routine Type.
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' Row%: row where input field will be placed
- ' Col%: starting column
- ' Length%: length of input field area
- ' (if a negative value is used for length, input field will
- ' be used for password entry - only * will be displayed)
- ' FieldText$: default text (null if none)
- ' Foreg%: foreground color attribute (0-15)
- ' Backg%: background color attribute (0-15)
- '
- '
- 'Return Values:
- '--------------
- ' >0: field successfully created (positive value is handle number)
- ' -1: field would extend beyond current window
- ' -4: not enough storage for another field
- ' [must increase value of global parameter MaxButtons]
- ' -5: foreground color attribute invalid (0-15)
- ' -6: background color attribute invalid (0-15)
- '
- '
- 'Notes:
- '------
- ' Row and column are relative to the current window.
- ' Row 0, Column 0, represent the first row/column in the window,
- ' regardless of where the window is located on the screen
- ' (first /last row and column contain the window's border).
- ' Input Field will not be opened if it would extend beyond boundaries
- ' of the current window (or if it would overlay the boundary itself).
- '
- ' The handle value returned must be saved.
- ' After calling WinEvent to wait for an event in the current window,
- ' you must determine which event occurred (see WinEvent for details).
- ' Depending upon the event, you may need to access/modify the contents
- ' of Input Fields in the window. Use the saved handles of all appropriate
- ' Input Fields to index the ButtonsText array which contains the
- ' contents of all fields. You can examine these contents to see their
- ' current values. If the contents contains numeric data, use VAL to
- ' extract the numeric value. Then use STR$ if the contents are to be
- ' updated with new numeric data (the contents of ButtonsText must always
- ' be STRING). Once the contents of ButtonsText have been modified,
- ' use the ReShowInputField subroutine to re-display the new contents
- ' in the current window.
- '
- ' If Han is the handle of an Input Field (returned by MakeInputField),
- ' the following code adds one to the Input Field and re-displays it:
- '
- ' value=VAL(ButtonsText(Han))+1 ' get value and increment by 1
- ' ButtonsText(Han)=STR$(value) ' update field's contents
- ' CALL ReShowInputField(Han) ' re-display input field
-
-
- ' By using a negative value for length, the input field can be used for
- ' password entry. In this case, regardless of what is entered, only *
- ' will be displayed. The actual text entered (i.e., the password) will
- ' be stored in ButtonsText(Han) - just as for any other input field.
- ' An alternative technique would be to use the same values for
- ' foreground and background colors. In this case, nothing will be visible
- ' when text is entered into the field.
-
- END FUNCTION
-
- FUNCTION MakePushButton.
-
- 'Purpose:
- '--------
- ' Open/display a Push Button in the current window.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' Row%: row where button will be placed
- ' Col%: starting column
- ' Length%: length of button area
- ' ButtonText$: text contents of button
- ' Foreg%: foreground color attribute (0-15)
- ' Backg%: background color attribute (0-15)
- ' Shadow%: switch: 0=no shadow; 1=shadow
- '
- '
- 'Return Values:
- '--------------
- ' >0: button successfully created (positive value is handle number)
- ' -1: button would extend beyond current window
- ' -3: length not big enough for all of ButtonText$
- ' -4: not enough storage for another button
- ' [must increase value of global parameter MaxButtons]
- ' -5: foreground color attribute invalid (must be 0-15)
- ' -6: background color attribute invalid (must be 0-15)
- ' -7: shadow switch value invalid (must be 0 or 1)
- '
- '
- 'Notes:
- '------
- ' Row and column are relative to the current window.
- ' Row 0, Column 0, represent the first row/column in the window,
- ' regardless of where the window is located on the screen
- ' (first /last row and column contain the window's border).
- ' Push Button will not be opened if it would extend beyond boundaries
- ' of the current window (on the border is ok - that's how a menu bar
- ' at top of window can be created).
- '
- ' The handle value returned must be saved.
- ' After calling WinEvent to wait for an event in the current window,
- ' you must determine which event occurred (see WinEvent for details).
- ' If the event was a button click, then WinEvent will return a 3, and
- ' you will need to determine exactly which button was selected. Compare
- ' the handle of the button that was clicked to all saved button handles.
- ' The action taken for each particular button handle is user defined
- ' based upon the meaning of the button.
- '
- ' If WinEvent returns a value of 3, then WinParms(CurWinPtr,16)
- ' contains the handle of the push button that caused the click (see
- ' WinEvent for additional details). The following code shows a technique
- ' for determining which button was clicked:
- '
- ' Han=WinParms(CurWinPtr,16) ' handle of button that was clicked
- ' SELECT CASE Han
- ' CASE b1
- ' ' action for button whose saved handle is b1
- ' CASE b2
- ' ' action for button whose saved handle is b2
- ' .
- ' .
- ' .
- ' END SELECT
-
- END FUNCTION
-
- FUNCTION MakeVertLine.
-
- 'Purpose:
- '--------
- ' Draw a vertical line down current window.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' Col%: column where line will be placed
- ' LineType%: type of line (1=single; 2=double)
- '
- '
- 'Return Values:
- '--------------
- ' 0: success
- ' 1: invalid line type parameter (must be 1 or 2)
- ' 2: line would extend beyond window boundary
- ' or fall on same column as border.
- '
- '
- 'Notes:
- '------
- ' Column where line is placed is relative to the current window.
- ' Column 0 represent the first column in the window,
- ' regardless of where the window is located on the screen
- ' (first /last column contains the window's border).
- ' Line will not be drawn if it would extend beyond boundaries of the
- ' current window (or if it would overlay the side boundaries).
-
- END FUNCTION
-
- FUNCTION MouseExists.
-
- 'Purpose:
- '--------
- ' Determines if the mouse driver has been installed.
- '
- '
- 'Routine Type:
- '-------------
- ' Function:
- '
- '
- 'Parameters:
- '-----------
- ' None.
- '
- '
- 'Return Values:
- '--------------
- ' TRUE (-1): mouse driver has been installed
- ' FALSE (0): mouse driver was not installed
- '
- '
- 'Notes:
- '------
- ' This routine does NOT install the mouse driver, it only checks
- ' to see if it exists.
- '
- ' It first looks in the interrupt vector table (segment 0) which has
- ' 4 bytes for each interrupt routine. The mouse interrupt (33h) vector
- ' begins at decimal 204 (33h=51d; 51d * 4 bytes/entry = 204).
- '
- ' If the 4 bytes at 204-207 are zero, the mouse driver not installed.
- ' Else, the contents of the address specified by the 4 bytes at 204-207
- ' are compared to the value 207 (i.e., an IRET instruction). If there is
- ' a match, mouse driver not installed. Otherwise, mouse driver assumed
- ' to be installed.
- '
- ' This routine is required for computers running DOS V2 or earlier.
- ' They leave the mouse interrupt (&h33) undefined if no mouse exists,
- ' and calling the mouse interrupt would crash the system.
- '
- ' Before using mouse functions, first call MouseExists to
- ' see if the driver has been installed. If it has, then call InitMouse
- ' to initialize the mouse driver. Once the driver has been successfully
- ' initialized, you can call other mouse functions.
-
- END FUNCTION
-
- SUB NewFocusWindow.
-
- 'Purpose:
- '--------
- ' Change the focus to a new window.
-
- ' (New with V2.0)
-
-
- 'Routine Type:
- '-------------
- ' Subroutine.
-
-
- 'Parameters:
- '-----------
- ' NewWinHan: handle of window to be given focus.
- '
- '
- 'Notes:
- '------
- ' On entry, CurWinPtr points to current window's handle.
- ' This window is top one in WinStack (entry with highest index).
-
- ' On exit, CurWinPtr will be set to NewWinHan.
- ' NewWinHan will be removed from WinStack (wherever it is),
- ' placed on top in WinStack (entry with highest index), and
- ' remaining handles pushed down.
-
- ' WARNING: if the input parameter (NewWinHan) is not a valid handle
- ' (i.e., NewFocusWindow scans WinStack for the handles of all open windows),
- ' then an error message is displayed (with the invalid handle's value),
- ' and the user's program is terminated. Thus, you should be very careful
- ' when calling NewFocusWindow to insure that you have a valid handle
- ' associated with an open window. See IsWinOpen which can be used to extract
- ' the handle of an open window given its window number.
- '
- ' Typical use of NewFocusWindow:
- ' EXIT button in main window was clicked (so main window has focus).
- ' Main window could have a child open. Before main window is closed,
- ' you need to close the child window (if it's open). Assume window number
- ' of child is saved in variable called ChildNum.
- ' IF IsWinOpen(ChildNum, han) THEN ' get handle of child
- ' zz = CurWinPtr ' save handle of main window (it's current)
- ' CALL NewFocusWindow(han) ' make child win current
- ' xx = CloseWindow ' close it
- ' CALL NewFocusWindow(zz) ' make main win current
- ' END IF
- ' xx = CloseWindow ' close main
-
-
- END SUB
-
- FUNCTION OpenScrollWindow.
-
- 'Purpose:
- '--------
- ' Open/display window with a scrollable text area.
- ' New window will be given focus.
- '
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'V2.0 Changes:
- '-------------
- ' Negative value for WinColor% will make window unmovable.
- ' New CloseIcon% parameter required.
- ' New ModeSw% parameter required.
- ' Negative value for ModeSw% will make window shadowless.
- ' Return values changed:
- ' Negative value returned if window not opened successfully.
- ' Window's number (>0) returned if window is opened successfully.
- ' 0 is not a valid return code.
- ' -11 is a new return code.
- ' -12 is a new return code.
-
-
- 'V2.3 Changes:
- '-------------
- ' In previous versions of LangWin, if OpenScrollWindow was called with
- ' UBOUND(Text$) > the global variable MaxTextLines, a run-time error would
- ' immediately terminate your program.
-
- ' As of V2.3, if UBOUND(Text$) > MaxTextLines,
- ' the scrollable text window will be opened, but only lines 1
- ' through MaxTextLines of the Text$ array will be scrollable. To let you
- ' know that all of the Text$ array is not available in the scroll window,
- ' the MaxTextLine entry will appear as: (Incomplete List)
- ' The original Text$ array will not be altered; Text$(MaxTextLine) remains
- ' unchanged. The string "(Incomplete List)" only appears in the window's
- ' scrollable list.
-
-
- 'Parameters:
- '-----------
- ' StartRow%: starting row (upper left)
- ' StartCol%: starting column (upper left)
- ' EndRow%: ending row (bottom right)
- ' EndCol%: ending column (bottom right)
- ' WinColor%: color attribute of window (0-15)
- ' (NEGATIVE value will make window unmovable)
- ' BorderColor%: color attribute of border (0-15)
- ' (NEGATIVE value will prevent window from being resized)
- ' BorderType%: 1=single line; 2=double line
- ' [if BorderType < 0 (i.e., -1 or -2), then no scroll
- ' bar or arrows will be displayed (even if text too big for
- ' win). use this option if you know that the number of lines
- ' of scrollable text is smaller than the lines available
- ' in the text window, AND you don't want scroll bar & arrows.
- ' if BorderType > 0, and number of
- ' lines of scrollable text is smaller than the window,
- ' then the scroll bar will automatically be omitted,
- ' but the scroll arrows will still be displayed.]
- ' TextColor%: color attribute for scrollable text in the window (0-15)
- ' (also used for close icon, scroll bar,and slider
- ' if present)
- ' Text$: array with text to be scrolled. will be placed into
- ' a vacant slot in SaveText array.
- ' Text$ MUST have lbound of 1 and NOT 0
- ' (see above comments about changes in V2.3)
- ' StartTextRow%: starting row of text area (relative to window)
- ' StartTextCol%: starting column of text area (relative to window)
- ' EndTextRow%: ending row of text area (relative to window)
- ' EndTextCol%: ending column of text area (relative to window)
- ' CloseIcon%: 1=display a close icon; 0=no close icon
- ' [regardless of whether a close icon is displayed, the ESC
- ' key will always generate a close action]
- ' ModeSw%: Mode of window (effects how/if/when WinEvent returns
- ' control after an action has taken place)
- ' (NEGATIVE value for mode will generate a shadowless window):
- ' 1 = modeless window (normal). if modeless window has
- ' focus, user can click on any other visible window
- ' and it will be given focus by WinEvent. WinEvent will
- ' continue to process the new window until an action
- ' is taken in the current window.
- ' 2 = modal window. if modal window has focus, any attempt
- ' to click on another window will be ignored by WinEvent.
- ' this type of window can be used to display a message,
- ' and force user to close the window before continuing
- ' (e.g., for error messages).
- ' 3 = if this type window has focus, clicking on another
- ' window, or even the wallpaper, will cause WinEvent to
- ' return a close action (1). This can be used for menu
- ' windows that should be closed if user clicks somewhere
- ' else on the screen.
- ' 4 = not valid for OpenScrollWindow (see BlankWin)
- '
- '
- 'Values Returned:
- '----------------
- ' >0: window opened successfully (window's number returned)
- ' -1: not enough storage for another new window.
- ' [must increase the global parameter MaxWindows]
- ' -2: not enough room for window's rows (+1 for shadow) on screen
- ' -3: not enough room for window's columns (+2 for shadow) on screen
- ' -4: window's color attribute out of range (must be 0-15)
- ' -5: window's border color attribute out of range (must be 0-15)
- ' -6: invalid value for BorderType (must be 1, 2, -1, or -2)
- ' -7: text color attribute out of range (must be 0-15)
- ' -8: window not long enough (must be >=3)
- ' -9: window not wide enough (must be >=3)
- '-10: defined text area will not fit into window
- '-11: no room in SaveText array for another block of text
- ' (increase value of MaxTextWins).
- '-12: invalid value for window mode (ModeSw) - must be 1 to 4
- '
-
- 'Notes:
- '------
- ' Internally, OpenScrollWindow calls BlankWin to open an empty window.
- '
- ' You MUST check to see if window opened successfully (return code>0)
- ' before calling any other LangWin functions or routines.
- ' Otherwise, you will either get errors (such as Illegal Function Call,
- ' Subscript Out of Range, etc.) or process the previously opened
- ' window by mistake.
-
- ' OpenScrollWindow calls BlankWin which sets the global
- ' variable AnyWinOpen to TRUE.
- ' this can be used to control a DO/LOOP that executes WinEvent
- ' as long as there is an open window on the screen. However, if an
- ' information only window is open, then you must use another criteria to
- ' end the DO/LOOP because the info only window will always be open.
- ' In this case, termination should occur when a close action
- ' occurs in the main window.
-
- ' The Text$ array passed to OpenScrollWindow contains lines of text to be
- ' displayed in a scrollable window. LBOUND(Text$) MUST be 1; otherwise
- ' a run-time error will terminate your program when OpenScrollWindow
- ' is called.
-
- ' If your array of scrollable text is generated dynamically at run time and
- ' its length could exceed MaxTextLines, then you MUST detect this condition
- ' and design your program to handle it. OpenScrollWindow will only display
- ' the first MaxTextLines in the string array (Text$) passed. The
- ' MaxTextLines entry in the scrollable list
- ' will be displayed as: (Incomplete List)
- ' So, your user will know that the complete list is not visible.
- ' However, your program should detect this condition and give the user
- ' the opportunity to see the missing entries.
-
- ' To see if this condition occured, merely compare UBOUND(Text$)
- ' to MaxTextLines. If UBOUND(Text$) > MaxTextLines, then part of the
- ' Text$ array will not be visible in the scrollable text window.
- ' In that case, you could offer the user an option to see more text,
- ' loop, delete the first MaxTextLines from the Text$ array, and
- ' open a new scrollable text window with the remaining lines.
- ' You'd continue this process until the user had the opportunity to
- ' see all of the original Text$ array. Another (easier) option is to
- ' give the user the ability to set MaxTextLines at run-time by initializing
- ' MaxTextLines from a parameter file. Of course, this opens the door
- ' for abuse: the user could pick a value so large that the program
- ' runs out of memory. I'll leave the actual solution to you!
-
- ' Null lines in the list of scrollable text cannot be given focus. If you
- ' scroll a list with null lines, the focus will disappear when you get to a
- ' null line. This can be confusing to the end user. Unless it's absolutely
- ' necessary, you should not include null lines in the Text$ array passed to
- ' OpenScrollWindow. OpenScrollWindow will not display any null lines at the
- ' end of the Text$ array. Null lines within the Text$ array will appear in
- ' scrollable list, but as previously mentioned, the focus will disappear
- ' when the user scrolls the highlight to one of these lines.
-
-
- END FUNCTION
-
- SUB RefreshScrollText.
-
- 'Purpose:
- '--------
- ' Redisplay new scrollable text in the current window with focus
- ' (the entire set of scrollable text is replaced).
-
-
- ' New with V2.0
- ' -------------
-
- ' Modified in V2.3
- ' ----------------
- ' In previous versions of LangWin, if RefreshScrollText was called with
- ' UBOUND(Text$) > the global variable MaxTextLines, a run-time error would
- ' immediately terminate your program.
-
- ' As of V2.3, if UBOUND(Text$) > MaxTextLines,
- ' the scrollable text window will be redisplayed, but only lines 1
- ' through MaxTextLines of the Text$ array will be scrollable. To let you
- ' know that all of the Text$ array is not available in the scroll window,
- ' the MaxTextLine entry will appear as: (Incomplete List)
- ' The original Text$ array will not be altered; Text$(MaxTextLine) remains
- ' unchanged. The string "(Incomplete List)" only appears in the window's
- ' scrollable list.
- '
-
- 'Routine Type:
- '-------------
- ' Subroutine.
-
-
-
- 'Parameters:
- '-----------
- ' Text$ - string array with new scrollable text to be displayed in the
- ' current window with focus.
- ' Text$ MUST have LBOUND of 1 and NOT 0
-
-
- 'Notes:
- '------
-
- ' The Text$ array passed to RefreshScrollText contains lines of text to be
- ' redisplayed in the current scrollable window. LBOUND(Text$) MUST be 1.
- ' If this conditions is not met (i.e., LBOUND(Text$) <> 1, then
- ' a run-time error will occur when RefreshScrollText is called.
-
- ' If RefreshScrollText is called and the current window with focus does not
- ' have scrollable text, then a run-time error will occur.
-
- ' Null lines in the list of scrollable text cannot be given focus. If you
- ' scroll a list with null lines, the focus will disappear when you get to a
- ' null line. This can be confusing to the end user. Unless it's absolutely
- ' necessary, you should not include null lines in the Text$ array passed to
- ' RefreshScrollText. Null lines at the end of Text$ are eliminated.
-
- ' RefreshScrollText works only on the current window. if you need to refresh
- ' text and are not sure if the window to be refreshed is current, then the
- ' following code can be used (assume you know that the variable win1
- ' contains the number of the window which is to be refreshed):
-
- ' IF IsWinOpen(win1,han) THEN ' if win1 is open, return its handle
- ' CALL NewFocusWindow(han) ' make win1 current
- ' CALL RefreshScrollText(Text$) ' update the window
- ' END IF
-
- END SUB
-
- SUB ReShowInputField.
-
- 'Purpose:
- '--------
- ' Re-display contents of an Input Field after it has been changed.
- ' Assumes that window containing the input field has focus.
- ' If it does not, call NewFocusWindow first to give focus to appropriate
- ' window.
-
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' Handle%: handle of Input Field to be displayed
- '
- '
- 'Notes:
- '------
- ' ButtonsText(Han) contains the text from the Input Field whose handle
- ' is Han. If your program modifies this text, you must re-display it
- ' in the current window (if you want the current window to reflect the
- ' change made to ButtonsText(Han)). Call ReShowInputField(Han) to
- ' accomplish this function.
- '
- ' See MakeInputField for additional details on creating an Input Field
- ' and the handle assigned to each field.
-
- END SUB
-
- SUB ReShowPage.
-
- 'Purpose:
- '--------
- ' Re-display all scrollable text lines that are visible in the current
- ' window. Useful if you have made changes to several lines of scrollable
- ' text and need to update the window. If window with scrollable text to
- ' be re-displayed is not current, first call NewFocusWindow to give
- ' focus to the appropriate window.
-
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
-
- 'V2.0 Changes:
- '-------------
- ' text array no longer needed as a parameter. text for all windows is
- ' saved in SaveText array when window is opened.
- '
-
- 'Parameters:
- '-----------
- ' None. (V2.0 change)
- '
- '
- 'Notes:
- '------
- ' You might define a button that causes action to be taken on selected
- ' lines of scrollable text (i.e., update all files whose names have been
- ' previously "selected" by double-clicking on them). After taking the
- ' necessary action, your code would toggle the "select" character in
- ' every line of text from on to off (i.e., change an "X" to a blank).
- ' After this has been done, the scrollable text that is visible in the
- ' current window must be re-displayed to reflect these changes. Use the
- ' ReShowPage routine to accomplish this function.
- '
- ' See ReShowText for details on re-displaying single lines of scrollable
- ' text in the current window (i.e., after a text line has been double-
- ' clicked and you change the contents of that text).
- ' See WinEvent for details on responding to events from the current
- ' window.
- '
- ' In general, you should not change the DIM of the scrollable text array
- ' while its window is open. Nor should you use ReShowPage to re-display
- ' a text array other than the one that was defined when the window was
- ' originally opened.
-
- END SUB
-
- SUB ReShowText.
-
- 'Purpose:
- '--------
- ' Re-display the currently highlighted scrollable text entry
- ' after it has been changed (one line is re-displayed).
- ' Assumes that window containing the scrollable text has focus.
- ' If it does not, call NewFocusWindow first to give focus to appropriate
- ' window.
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
-
- 'V2.0 Changes:
- '-------------
- ' text array no longer needed as a parameter. text for all windows is
- ' saved in SaveText array when window is opened.
- '
- '
- 'Parameters:
- '-----------
- ' none. (v2.0 change)
- '
- '
- 'Notes:
- '------
- ' If the currently highlighted line of scrollable text is changed by your
- ' program in response to some event or process, then use ReShowText to
- ' re-display the modified line of text in the current window. For
- ' example, if you detect, via WinEvent, a double-click on a line of
- ' scrollable text, and you want to mark that line as "selected" before
- ' going back and waiting on another event, you could change a specific
- ' character in the selected text line (i.e., change a blank to an X) and
- ' re-display it with ReShowText. In this example, WinEvent would return a
- ' value of 2 (signifying that a line of scrollable text was double-
- ' clicked) and WinParms(CurWinPtr,15) would contain the index, in your
- ' array of scrollable text, that was selected; that is:
- ' Text$(WinParms(CurWinPtr,15)) was double-clicked. After making the
- ' appropriate changes to the selected line in the Text$ array,
- ' CALL ReShowText(Test$()) to re-display it in the visible window.
- '
- ' You might also have a button whose function is to take action on all
- ' selected lines of scrollable text. After detecting that this button was
- ' clicked, via WinEvent, and taking the necessary action, you would
- ' change all the characters that had been set to denote selection
- ' (say an X) back to a character that denotes no selection (say a blank)
- ' and then re-display all lines of scrollable text that are currently
- ' visible in the window (see ReShowPage).
- '
- ' See WinEvent for details on responding to events from the current
- ' window.
- '
- ' In general, you should not change the DIM of the scrollable text array
- ' while its window is open. Nor should you use ReShowPage to re-display
- ' a text array other than the one that was defined when the window was
- ' originally opened.
-
- END SUB
-
- SUB SetColor.
-
- 'Purpose:
- '--------
- ' Set foreground/background color attributes. When using LangWin,
- ' SetColor MUST be used instead of BASIC's COLOR command.
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' Foreg%: foreground color attribute (0-15)
- ' Backg%: background color attribute (0-15)
- '
- '
- 'Notes:
- '------
- ' LangWin uses BIOS interrupt 10h, function 10h, sub-function 03h to
- ' disable blinking colors. This allows 16 attribute numbers for window
- ' (background) colors (rather than just 8). However, with blinking
- ' disabled, foreground/background attribute numbers MUST be translated
- ' before calling BASIC's COLOR command. SetColor does this translation.
- ' If BASIC's COLOR command is called without this translation, you will
- ' get unexpected colors.
- '
- ' If you need to change colors in any program that uses LangWin's
- ' routines, use SetColor just as you would use BASIC's COLOR command.
-
- END SUB
-
- SUB SetMousePos.
-
- 'Purpose:
- '--------
- ' Sets the current position of the mouse pointer (in pixel coordinates).
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' Horiz%: new horizontal pixel coordinate of mouse.
- ' Vert%: new vertical pixel coordinate of mouse.
- '
- '
- 'Notes:
- '------
- ' This subroutine calls BIOS interrupt 33h, function 04h.
- '
- ' Horizontal/vertical coordinates set are in PIXELS. If you know the
- ' new column/row position, use integer multiplication by width/depth of
- ' character in pixels to get pixel coordinates.
- '
- ' Also see: GetMousePos and GetButtonPress
-
- END SUB
-
- SUB SetXLimit.
-
- 'Purpose:
- '--------
- ' Set horizontal limits for mouse pointer.
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' MinX%: minimum horizontal coordinate (in pixels)
- ' MaxX%: maximum horizontal coordinate (in pixels)
- '
- '
- 'Notes:
- '------
- ' Use this routine to restrain mouse pointer to a specific
- ' horizontal area. Current mouse pointer will automatically
- ' be moved into the allowable area if necessary.
- '
- ' BIOS interrupt 33h, function 07h is used.
- '
- ' Also see: SetYLimit
-
- END SUB
-
- SUB SetYLimit.
-
- 'Purpose:
- '--------
- ' Set vertical limits for mouse pointer.
- '
- '
- 'Routine Type:
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' MinY%: minimum vertical coordinate (in pixels)
- ' MaxY%: maximum vertical coordinate (in pixels)
- '
- '
- 'Notes:
- '------
- ' Use this routine to restrain mouse pointer to a specific
- ' vertical area. Current mouse pointer will automatically
- ' be moved into the allowable area if necessary.
- '
- ' BIOS interrupt 33h, function 08h is used.
- '
- ' Also see: SetXLimit
-
- END SUB
-
- SUB ShowMouseCursor.
-
- 'Purpose:
- '--------
- ' Displays the mouse cursor.
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' None.
- '
- '
- 'Notes:
- '------
- ' This subroutine calls BIOS interrupt 33h, function 01h.
- '
- ' The mouse cursor must be hidden before writing anything to the screen.
- ' Otherwise, any character written to the same position as the mouse
- ' cursor will not be displayed. HideMouseCursor accomplishes this task.
- ' ShowMouseCursor is then used to re-display the mouse cursor.
- '
- ' LangWin sets a global flag (HaveMouse) to true if mouse exists.
- ' This flag should be tested before calling ShowMouseCursor:
- ' IF HaveMouse THEN CALL ShowMouseCursor
- '
- ' Also see: HideMouseCursor, MouseExists, and InitMouse.
-
- END SUB
-
- FUNCTION ShowTitle.
-
- 'Purpose:
- '--------
- ' Display a title bar, centered at the top of the current window.
- ' If appropriate window to contain title does not have focus,
- ' call NewFocusWindow to make it current.
- '
- ' V2.1 Changes: return code 1 eliminated, return code 4 added.
-
-
- 'Routine Type:
- '-------------
- ' Function.
- '
- '
- 'Parameters:
- '-----------
- ' Title$: string with title
- ' Foreg%: foreground color attribute (0-15)
- ' Backg%: background color attribute (0-15)
- '
- '
- 'Return Values:
- '--------------
- ' 0: title successfully displayed
- ' 2: background color attribute invalid (must be 0-15)
- ' 3: foreground color attribute invalid (must be 0-15)
- ' 4: not enough storage for another title (new with V2.1)
- ' [must increase value of global parameter MaxButtons]
-
- 'Notes:
- '------
- ' With LangWin V2.1, return code 1 is no longer used (this return
- ' code used to indicate that the title was too wide for the window).
- ' If the title is too wide, it will be truncated, and code 0 returned.
-
- ' Also with LangWin v2.1, resizing has been implemented. Title data is
- ' saved in data structures so it can be re-displayed when a window is
- ' resized. Code 4 is returned if there is no more room in the data
- ' structures (i.e., ButtonsText and ButtonsData). In this case, you'll
- ' need to increase the value of the global variable MaxButtons.
- END FUNCTION
-
- FUNCTION ShowWinText.
-
- 'Purpose:
- '--------
- ' Display a line of static (non-scrollable) text in current window.
- ' If appropriate window to contain text is not current, first call
- ' NewFocusWindow to make it current.
-
- '
- 'Routine Type:
- '-------------
- ' Function:
- '
- '
- 'Parameters:
- '-----------
- ' Row%: row where text will be placed
- ' Col%: starting column
- ' Foreg%: foreground color attribute (0-15)
- ' Text$ string with static text to be displayed
- '
- '
- 'Return Values:
- '--------------
- ' 0: text successfully displayed
- ' -1: text extends beyond current window
- ' -3: foreground color not valid (must be 0-15)
- ' -4: not enough storage for to save this text (new with V2.1)
- ' [must increase value of global parameter MaxButtons]
- '
- '
- 'Notes:
- '------
- ' Row and column are relative to the current window.
- ' Row 0, Column 0, represent the first row/column in the window,
- ' regardless of where the window is located on the screen
- ' (first /last row and column contain the window's border).
- ' Window text will not be displayed if it would extend beyond boundaries
- ' of the current window (on the border is ok).
-
- ' To display numeric values in a window, use STR$(number) in the Text$
- ' parameter. For example:
- ' CALL ShowWinText(2, 3, 15, "Number of Wigits: " + STR$(NumWig))
-
- ' With LangWin v2.1, resizing has been implemented. Static text data is
- ' saved in data structures so it can be re-displayed when a window is
- ' resized. Code -4 is returned if there is no more room in the data
- ' structures (i.e., ButtonsText and ButtonsData). In this case, you'll
- ' need to increase the value of the global variable MaxButtons.
-
- ' Static text created by ShowWinText can be modified/changed by calling
- ' ShowWinText again, with the same row/column but new text. This is
- ' acceptable when only a few updates are needed. However, if the static text
- ' is modified based upon some user action (like a button click), then there
- ' is no way to determine the number of times the text will be modified. Each
- ' time ShowWinText is called, the text is saved in LangWin's data structures
- ' (ButtonsText and ButtonsData). These structures have a finite dimension
- ' (MaxButtons). Each call to ShowWinText requires a new entry in the data
- ' structures. Thus, repeated calls to modify text can exhaust all available
- ' slots. In this case, the result would be that subsequent calls to create
- ' objects (either new buttons, input fields, check boxes, or static text)
- ' will fail and the object will not appear. Closing a window will free all
- ' slots occupied by its objects. Increasing the value of MaxButtons will make
- ' more slots available. However, neither of these is a good solution. A
- ' better solution is to re-use the same slot whenever existing static text is
- ' modified. All that is needed is to first determine the slot number (handle)
- ' of the static text, then to update the contents of the existing slot and
- ' re -display it.
-
- ' Since ShowWinText returns an error code and not the handle of the slot used
- ' to store text, you'll need to find and save the handle number in order to
- ' later modify its contents. The best way to do this is to use ShowWinText to
- ' temporarily place some specific text into the data structures, then
- ' manually scan the data structure until you find the specific text. The
- ' following code will accomplish these tasks:
-
-
- ' x = ShowWinText(r, c, colr, "SOME UNIQUE TEXT")
- ' ' the above will place "SOME UNIQUE TEXT" at row=r, column=c in the
- ' ' current window using color=colr. the string "SOME UNIQUE TEXT"
- ' ' will also be placed into the next available slot in ButtonsText
- ' IF x < 0 THEN
- ' ' if error condition, process it
- ' END
- ' END IF
- '
- ' thandle = -999 ' set a default value for the handle
- '
- ' ' now search ButtonsText for the specific text string
- ' FOR i = 1 TO MaxButtons
- ' IF ButtonsText(i) = "SOME UNIQUE TEXT" THEN
- ' thandle = i ' save handle number
- ' EXIT FOR ' quit serach
- ' END IF
- ' NEXT
- '
- ' ' just in case the "impossible" happens
- ' IF thandle = -999 THEN
- ' ' process the error
- ' END
- ' END IF
-
- ' At this point, the variable: thandle points to the slot in LangWin's data
- ' structures that contains the temporary static text. The screen itself
- ' displays the temporary text at the designated row/column. Now, you must
- ' replace the temporary text with the initial value of the static text (using
- ' the same slot in the data structures) and display this text on the screen.
- ' The following code will accomplish these tasks:
-
- ' a$ = "initial contents of static text field"
- ' ButtonsText(thandle) = a$ ' update text in data structure
- ' CALL ReShowInputField(thandle) ' redisplay text on screen
- ' ButtonsData(thandle, 4) = LEN(a$)' update length of text area
-
- ' You might ask: why is the length of the text in LangWin's data structure
- ' updated AFTER the text is displayed? Glad you asked that question!
- ' ReShowInputField (which is really meant to redisplay the contents of an
- ' input field after it has been modified, but will also redisplay static
- ' text) first clears the entire contents of the area, then displays the
- ' new text. The length of the area to clear is obtained from the data
- ' structure. So, if the length of the new text was smaller than the previous
- ' text, and the new (smaller) length was first placed into the data structure,
- ' then only the smaller area would cleared prior to displaying the new text.
- ' Any characters from the previous (longer) text beyond the end of the new
- ' (smaller) text would remain on the screen. By calling ReShowInputField
- ' before the length is updated, the length of the area cleared will
- ' correspond to the the current text.
-
- ' Later in your program, when you determine that new static text must be
- ' placed into the window at the same position as the old text, the following
- ' code can be used:
-
- ' a$ = "new contents of static text field"
- ' ButtonsText(thandle) = a$ ' update text in data structure
- ' CALL ReShowInputField(thandle) ' redisplay text on screen
- ' ButtonsData(thandle, 4) = LEN(a$)' update length of text area
-
- ' These techniques can be used with any number of static text entries. You'll
- ' just need to save each handle in a unique variable name.
-
-
-
- END FUNCTION
-
- SUB WaitTicks.
-
- 'Purpose:
- '--------
- ' A timed delay similar to SLEEP but more granular.
- '
- '
- 'Routine Type:
- '-------------
- ' Subroutine.
- '
- '
- 'Parameters:
- '-----------
- ' Ticks%: number of timer ticks to "sleep".
- ' this parameter MUST be between 0 and 255.
- ' each "tick" is approximately (1/18.2) seconds.
- '
- 'Notes:
- '------
- ' Address 0040:006Ch is a 32-bit timer that is incremented approximately
- ' 18.2 times per second. This routine examines the low byte of this
- ' timer, and waits for the specified number of increments (ticks)
- ' to elapse before returning. While any value up to 255 is valid for the
- ' input parameter (i.e., the maximum value of a byte), in practice, you
- ' should only need input values from 0 - 18.
- ' For values greater than 18 (i.e., to wait more than one second),
- ' use the SLEEP function instead (whose granularity is in seconds).
- '
- ' Use WaitTicks if you need to delay for some period less than a second.
- ' It is also useful if you need your code to wait a consistent amount of
- ' time regardless of what speed/model CPU it runs on. A FOR/NEXT delay
- ' loop will not produce consistent delays across different speed CPUs.
-
- END SUB
-
- FUNCTION WinEvent.
-
- 'Purpose:
- '--------
- ' Wait for an event to occur in the current window.
- ' This routine should be called AFTER opening a window and
- ' any associated buttons, text, input fields, check boxes, etc.
-
- ' This routine will automatically handle mouse clicks on other underlying
- ' visible windows. If appropriate (see ModeSw in BlankWindow and
- ' OpenScrollWindow), the underlying window clicked will be given focus.
- ' When control is returned from WinEvent, its return code will be the
- ' current window's number. In addition, WinEvent's action parameter
- ' will be set to one of the following values:
- ' 1) close was selected; 2) scrollable text entry selected;
- ' or 3) push button selected. user also can define global hot keys and
- ' corresponding action codes returned when key is hit.
- '
- ' If an "information only" window has been opened (i.e., one for which
- ' there are no events that can occur), then WinEvent need not be called.
- ' The information only window, however, should be closed when it is no
- ' longer needed.
- '
- 'Routine Type:
- '-------------
- ' Function.
- '
-
- 'V2.0 Changes:
- '-------------
- ' string array with scrollable text no longer needed as parameter.
- ' parameter is an action code for event in the window (see below).
- ' value of WinEvent returned is either -1 (error occurred) or
- ' the window's number that is current (i.e., that generated the action).
-
- ' WinEvent no longer locks the mouse on the current window.
- ' User can select other visible windows.
-
- 'V2.3 Changes:
- '-------------
- ' "Time Out" feature added. If the action% parameter passed is -999, then
- ' WinEvent will return control to the calling program after 0.5 seconds if
- ' no events are detected (see Notes for more details).
-
- 'Parameters:
- '-----------
- ' action%: a return code representing the action that occurred in the
- ' current win (if action% is set to -999 upon entry, the "time
- ' out" feature will be enabled).
-
- ' 1 => close event (ESC key, close button double clicked,
- ' or Mode 2 window was current and user clicked on
- ' some other window or wallpaper).
-
- ' 2 => scrollable text selected (double click in scrollable text,
- ' or ENTER hit while a specific line of scrollable text had
- ' FOCUS and no other buttons had FOCUS).
- ' SaveText(i,j) is text selected; where
- ' i=WinParms(CurWinPtr,18)
- ' j=WinParms(CurWinPtr,15)
-
- ' 3 => button selected (double click on push button or ENTER hit
- ' while a specific button had FOCUS).
- ' handle of button = WinParms(CurWinPtr,16)
- ' ButtonsText(handle) contains the button's text
- ' (or null if button is not active)
- ' ButtonsData(handle,i) contains info on button
-
- ' >=4 => user defined hot keys can be associated with an action
- ' code that is returned whenever a hot key is hit.
-
- ' -999 => if action% is set to -999 upon entry to WinEvent, then the
- ' "time out" feature will be enabled. this feature will cause
- ' control to be returned to the calling program if no events
- ' are detected within 0.5 seconds. see Notesd for additional
- ' details.
-
- 'Values Returned:
- '----------------
- ' -1: error occurred
- ' >0: window number with FOCUS when event occurred.
-
-
- '
- 'Notes:
- '------
- '
- ' WinEvent is the workhorse of LangWin. After opening a window(s) and
- ' defining buttons, scrollable text, check boxes, input fields, etc., you
- ' must call WinEvent to wait for an event/action to occur.
- ' WinEvent returns two important values: the WinEvent function returns
- ' the window's number that had FOCUS when the event occurred. The action
- ' parameter defines what event took place in the current window.
-
- ' WinEvent processes all GUI functions in all visible windows. Some events
- ' are handled entirely within WinEvent (i.e., mouse movements, scrolling,
- ' changing FOCUS among windows or items in the window, clicking/un-clicking
- ' check boxes, entering values into input fields). Other events will cause
- ' WinEvent to return control to your program.
-
- ' There are 3 pre-defined generic events/actions that will cause WinEvent to
- ' return control to the calling program: the close icon (upper right) was
- ' double clicked (or ESC hit), a line of scrollable text was double
- ' clicked (or ENTER was hit while the scrollable text had FOCUS and no
- ' other button had FOCUS), or a push button was single clicked (or ENTER
- ' was hit while the button had FOCUS). You can also define Hot Keys, and
- ' corresponding WinEvent action codes. Each user-defined Hot Key is also
- ' considered a window event. When a Hot Key is selected, WinEvent returns
- ' control to the calling program with the corresponding user-defined
- ' action code for that Hot Key.
- '
- ' The value of the WinEvent function corresponds to the window's number
- ' that generated the above action.
- ' First, an explanation of the difference between a window's number and its
- ' handle is necessary. When a window is opened (BlankWindow or
- ' OpenScrollWindow), it is given a unique number. Data for the window is
- ' stored in several arrays, and the index to these arrays is called the
- ' window's handle (CurWinPtr is a global variable containing the handle
- ' of the window currently in FOCUS). The slots of the arrays are re-used
- ' as windows are opened and closed, so the window's handle cannot be used
- ' to uniquely determine the window. The window's number is a sequential
- ' value which is never re-used. Thus handle number 3 might point to data
- ' for window number 6 at one point, and after that window is closed and
- ' another is opened, handle number 3 could then point to data for window
- ' number 7. This is why WinEvent returns the window's number that generated
- ' the event. If it returned the handle, you could not be sure exactly which
- ' window was currently pointed to by the handle (and thus how to handle the
- ' action from that window). WinNum is a cross reference array containing
- ' window numbers. WinNum(i) contains the window number that corresponds to
- ' handle i.
-
- ' In general, WinEvent should be placed at the top of a DO/LOOP. After
- ' returning control to your program, test WinEvent's value to determine
- ' which window number had FOCUS, then for each possible window number that
- ' your program could open, process the particular event/action.
- ' You can determine if any information was entered into input fields,
- ' if check boxes were selected, if buttons were clicked, etc. in the
- ' current window.
-
- ' the global variable AnyWinOpen can be used to control the DO/LOOP.
- ' It will be TRUE as long as there is an open window on the screen. However,
- ' if an information only window is open (i.e., one with text only where
- ' no events could occur), then you must use another criteria
- ' to end the DO/LOOP because the info only window will always be open.
- ' In this case, termination should occur when a close action
- ' occurs in the main window.
-
- ' Prototype code would look like this:
-
- ' open some windows and make buttons, etc.
- ' window numbers saved in variables win1 and win2
-
- ' win1=OpenScrollWindow(......)
- ' make some buttons
- ' win2=OpenScrollWindow(....)
- ' make some buttons
-
- ' DO WHILE AnyWinOpen
- ' wnum=WinEvent(action) ' wnum= win number; action= action code
- ' SELECT CASE wnum
-
- ' CASE win1
- ' SELECT CASE action
- ' CASE 1 ' close
- ' process the close action
- ' CASE 2 ' text selected
- ' process the selected text
- ' CASE 3 ' button clicked
- ' process the button
- ' END SELECT
-
- ' CASE win2
- ' SELECT CASE action
- ' CASE 1 ' close
- ' process the close action
- ' CASE 2 ' text selected
- ' process the selected text
- ' CASE 3 ' button clicked
- ' process the button
- ' END SELECT
-
- ' END SELECT
- ' LOOP
-
- '
- ' A brief description on how to process window events will be
- ' given here. Refer to LANGWIN.DOC and the sample programs distributed
- ' with LangWin for more details.
- '
- ' Three data structures contain information necessary to process
- ' window events: WinParms(CurWinPtr,i): data on current window
- ' ButtonsData(Handle,i): data on all buttons/fields
- ' ButtonsText(Handle): text contents of buttons/fields
- '
- ' CurWinPtr: is a global parameter maintained by LangWin.
- ' It always points to the current window's handle.
- ' Handle: is the value assigned to the button/box/field when
- ' it was opened (see: MakePushButton, MakeCheckBox,
- ' and MakeInputField)
- ' i: represents an index into the structure
-
- ' Suggested processing for the various actions/events returned by WinEvent:
- '
- ' CLOSE EVENT (code = 1):
- ' Not much to do here.
- ' CALL CloseWindow to close the current window.
- ' Then continue processing the DO/LOOP with WinEvent as long
- ' as other windows are still open.
- '
- ' SCROLLABLE TEXT EVENT (code = 2):
- ' A line of scrollable text was selected.
- ' SaveText(i,j) contains the selected text; where
- ' i=WinParms(CurWinPtr,18)
- ' j=WinParms(CurWinPtr,15)
- '
- ' Process the selected text line as appropriate.
- ' For example, if the contents of SaveText(i,j) must be modified (i.e.,
- ' a "select" character toggled), then update the text line as necessary.
- ' After updating the text, CALL ReShowText to
- ' re-display the new text in the current window. The scrollable
- ' text could consist of parameters that, when selected, will cause
- ' additional processing (and maybe additional windows to be open).
- ' Use the values of i and j to determine which line in your scrollable
- ' parameter list was selected (and thus what additional processing
- ' and/or windows are needed).
- '
- ' After all processing has been completed for the text line selected,
- ' continue with the WinEvent loop.
-
-
- '
- ' PUSH BUTTON EVENT (code = 3):
- ' A specific Push Button was selected. WinParms(CurWinPtr,16)
- ' contains the Handle for that button. Using that Handle, you
- ' should compare it to the handles of all buttons created for the given
- ' window that generated the event (all button handles assigned by
- ' MakeCheckBox and MakeInputField should be saved in variables).
- ' When you find a match, process the button action as necessary.
-
- ' Prototype might look like this (assume button1 & button2 variables
- ' contain handles of buttons created for the window):
-
- ' CASE 3 ' button clicked
- ' handle=WinParms(CurWinPtr,16)
- ' SELECT CASE handle
- ' CASE button1
- ' code to process button1
- ' CASE button2
- ' code to process button2
- ' END SELECT
-
- ' You may need to determine which text line had FOCUS when the Push
- ' Button was selected, and you may need to determine if any Input
- ' Fields or Check Boxes were modified prior to the Push Button being
- ' selected.
- '
- ' If WinParms(CurWinPtr,15) contains a -1, then no scrollable text
- ' exists in the current window. Otherwise SaveText(i,j) had FOCUS
- ' when the button was selected. Where:
- ' i=WinParms(CurWinPtr,18)
- ' j=WinParms(CurWinPtr,15)
-
- ' To determine if any Input Field was modified, examine the contents
- ' of all Input Fields in the given window using the handles saved
- ' when you created the Input Field. Knowing the previous contents
- ' of the Input Field, and its handle, test the value of
- ' ButtonsText(handle). Take appropriate action if Input Field
- ' was updated. If your program modifies an input field, then CALL
- ' ReShowInputField to re-display the new Input Field in the current
- ' window.
-
- ' To determine the state of any Check Boxes in the current window, use
- ' its Check Box handle (saved when you created the check boxes) and
- ' examine ButtonsData(Handle,7). If this is a 1, then the Check Box
- ' corresponding to Handle was not set. If this is a 0, then the box was
- ' set. Do all necessary processing based upon the state of Check Boxes.
- '
- ' After all processing has been completed for the button selected,
- ' continue with the WinEvent loop.
-
-
-
- ' Calling WinEvent with action% set to -999 will enable the "time out"
- ' feature. This feature will cause WinEvent to return control to the
- ' calling program if no events are detected after 0.5 seconds. This
- ' can be used to implement an "interrupt" button for long running tasks.
-
- 'In order to interrupt a long running task, place the task in a loop with a
- 'call to WinEvent (with time out feature enabled). Each time through the loop,
- 'some portion of the long running task is completed (like reading one record
- 'from a large file, scanning one directory, whatever portion of the overall
- 'task that is appropriate). After completing a portion of the long running
- 'task, call WinEvent with the time out feature. After the call to WinEvent,
- 'determine what (if any) event occurred. If the event was a click on your
- 'interrupt button, exit the loop that processed the long running task. If no
- 'event occurred (i.e., WinEvent timed out after 0.5 seconds), then loop and
- 'perform more work on the long running task.
-
- 'Here's some pseudo code. Assume this code gets control when a "start" button
- 'is clicked to initiate the long running task. Also assume that prior to this
- 'point, a MODAL window was opened with start and interrupt buttons for the
- 'long running task. Finally, assume that the long running task is to read all
- 'records from a file.
-
- ' CASE StartButton
- ' deactivate "start" button (don't need it now)
- ' activate "interrupt" button (assume it was previously inactive)
- ' open a file (assume the long running task is to read a file)
-
- ' ' process long running task
- ' DO
- ' read a record (assume the long running task is to read a file)
- ' update screen to show some kind of progress
- ' if EOF then EXIT DO ' see if task is done
- ' act=-999 ' to activate time out feature
- ' wn=WinEvent(act) ' get an action or time out
- ' LOOP UNTIL interrupt button action detected
-
- ' ' long running task completed or interrupted
-
- ' deactivate "interrupt" button (not needed now)
- ' activate the "start" button (if it's needed)
- ' close file
- ' process the data
- ' close the current window (if it's no longer needed)
-
-
- 'Note that you should not attempt to do too much work in your loop before
- 'periodically giving control to WinEvent (to see if the interrupt button was
- 'clicked). WinEvent is not aware of mouse clicks made before it is called
- 'because it must hide and re-show the mouse cursor during initialization
- '(which causes the mouse driver to zero the mouse press counter). Thus, if you
- 'do a lot of processing before calling WinEvent, your user could have been
- 'attempting to click the interrupt button for awhile with no response. You'll
- 'have to experiment, and tune your code so that it gets back to WinEvent
- 'quickly. If you notice that the interrupt button needs to be clicked very
- 'frequently before it is recognized, then the cause is probably due to an
- 'excessive amount of time consumed by your task in between iterations of the
- 'loop where WinEvent is called.
-
- 'I strongly recommend that the window you open, with buttons to start and
- 'interrupt the long running task, be MODAL (i.e., only events in that window
- 'will be recognized by WinEvent, events in other windows will be ignored). The
- '"in-line" call to WinEvent (in the loop that processes your long running task)
- 'will restrict the events recognized by your program to just those that you
- 'explicitly test after returning from WinEvent (the code you have elsewhere
- 'in your program to handle other buttons in other windows will not be given
- 'control). If the window with the start and interrupt buttons is not modal,
- 'then your user will be able to mouse to other windows, make them active, and
- 'click their buttons. This will have visual effects (active windows will move
- 'to the top, clicked buttons will move); however, unless explicit code to
- 'handle these events (in other windows) is included in your loop with the long
- 'running task, the clicks on other buttons will be ignored. This will confuse
- 'your user. By making the window with the start and interrupt buttons modal,
- 'your user will not be able to mouse to another window to make it active, and
- 'clicking objects on other windows will show no visual effect.
-
- 'See SAMPLE05.BAS for an example of the technique for using WinEvent's time
- 'out feature to implement an interrupt button.
-
- END FUNCTION
-
-